import React from 'react';
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit'; // xterm.js的插件，使终端的尺寸适合包含元素
import { WebLinksAddon } from 'xterm-addon-web-links';
import { AttachAddon } from 'xterm-addon-attach'
import { message } from 'antd';
import 'xterm/css/xterm.css'; // 引入样式文件
const fitAddon = new FitAddon();
class Term extends React.Component {

    constructor(props) {
        super(props);
        this.terminalContainerRef = React.createRef();
    }

    initTerminal = () => {
        //CONNECTING
        this.xterm = new Terminal({
            // cursorStyle: 'underline', //光标样式

            windowsMode: true, // 根据窗口换行,
            // rendererType: "canvas", //渲染类型
            // rows: 80, //行数
            // cols: this.cols,// 设置之后会输入多行之后覆盖现象
            convertEol: true, //启用时，光标将设置为下一行的开头
            // scrollback: 10,//终端中的回滚量
            // fontSize: 14, //字体大小
            // disableStdin: false, //是否应禁用输入。
            // cursorStyle: "block", //光标样式
            cursorBlink: true, //光标闪烁
            // scrollBack: 30,
            // tabStopWidth: 4,
            theme: {
                foreground: "yellow", //字体
                background: "#060101", //背景色
                cursor: "help" //设置光标
            }
            // 其它配置可查看源码
        });
        this.xterm.loadAddon(new AttachAddon(this.socket));

        this.xterm.loadAddon(fitAddon);
        this.xterm.loadAddon(new WebLinksAddon());
        this.xterm.open(this.terminalContainerRef.current);
        fitAddon.fit();
        this.xterm.focus();

        this.xterm.onData(data => {
            let dataWrapper = data;
            if (dataWrapper === '\r') {
                dataWrapper = '\n';
            } else if (dataWrapper === '\u0003') {
                // 输入ctrl+c
                dataWrapper += '\n';
            }
            // this.socket.send(JSON.stringify({ Op: 'stdin', data: dataWrapper }));
            // this.socket.send(dataWrapper);
        });
    }


    componentDidMount() {
        // this.initTernimal();
        this.connect(); // 连接websocket
        // 监听页面resize，实时调整terminal的rows，cols
        window.addEventListener('resize', this.onTerminalResize);
    }
    connect = () => {
        let url = `ws://127.0.0.1:3100/ws/webshell`;
        console.log('开始连接WS',url);
        this.socket = new WebSocket(url);
        this.socket.onopen = this.onConnectionOpen.bind(this);
        // this.socket.onmessage = this.onConnectionMessage.bind(this);
        this.socket.onerror = this.onConnectionError.bind(this);
        this.socket.onclose = this.onConnectionClose.bind(this);
    }
    onConnectionError() {
        message.error('socket 连接错误')
    }
    // 连接建立成功后的挂载操作
    onConnectionOpen() {
        console.log('socket open.')
        message.success("WsSocket连接成功")
        this.initTerminal();
        this.onTerminalResize();
    }
    onConnectionClose(evt) {
        this.xterm.writeln('Connection closed');
    }
    onConnectionMessage(evt) {
        try {
            if (typeof evt.data === 'string') {
                console.log(evt.data)
                // const msg = JSON.parse(evt.data);
                // 将返回的数据写入xterm，回显在webshell上
                // this.xterm.write(evt.data);

                // 此处可以判断一下，如果是首次连接，需要将rows，cols传给服务器端
                // when server ready for connection,send resize to server
                //this.socket.send(
               //     JSON.stringify({
                //        rows: this.xterm.rows,
               //         cols: this.xterm.cols
               //     })
               // );
            }
        } catch (e) {
            console.error(e);
            console.log('parse json error.', evt.data);
        }
    }
    UNSAFE_componentWillMount() {
        if (this.socket) {
            this.socket.close();
        }
        window.removeEventListener('resize', this.onTerminalResize);
    }


    onTerminalResize = () => {
        const terminalContainer = this.terminalContainerRef.current;
        if (!terminalContainer) {
            return;
        }
       const width = terminalContainer.parentElement.clientWidth;
        const height = terminalContainer.parentElement.clientHeight;
        const { xterm } = this;
        // 计算cols，rows
        const cols = (width - xterm._core.viewport.scrollBarWidth-15) / xterm._core._renderService._renderer.dimensions.actualCellWidth;
        const rows = height / xterm._core._renderService._renderer.dimensions.actualCellHeight - 1;
        this.xterm.resize(
            parseInt(cols.toString(), 10),
            parseInt(rows.toString(), 10)
        );
        fitAddon.fit();
    };

    render() {
        return (<div style={{overflow:'auto'}} ref={this.terminalContainerRef}></div>);
    }

}

export default Term
